package com.derschmale.wick3d.core.pipeline
{
	import com.derschmale.wick3d.cameras.Camera3D;
	import com.derschmale.wick3d.core.bsp.BspTree;
	import com.derschmale.wick3d.core.geometry.Triangle3D;
	import com.derschmale.wick3d.debug.GeneralStatData;
	import com.derschmale.wick3d.display3D.BSPWorld3D;
	import com.derschmale.wick3d.display3D.World3D;
	import com.derschmale.wick3d.view.Viewport;
	
	import flash.display.Graphics;
	
	/**
	 * The BSPRenderPipeline class is the main hub for the Wick3d rendering process when using a BSP Tree. It eliminates z-sorting issues, but can only be used in scenes in which the camera can move, but the objects itself cannot.
	 * 
	 * @see com.derschmale.wick3d.core.bsp.BspTree
	 */
	public class BSPRenderPipeline extends RenderPipeline
	{
		private var _bspTree : BspTree;
		
		/**
		 * Creates a BSPRenderPipeline instance.
		 * 
		 * @see com.derschmale.wick3d.core.bsp.BspTree
		 */
		public function BSPRenderPipeline()
		{
			super();
		}
		
		override public function render(world:World3D, camera:Camera3D, target:Viewport):void
		{
			if (!(world is BSPWorld3D)) {
				throw(new ArgumentError("Parameter world in BSPRenderPipeline::render should be of type BSPWorld3D"));
			}
			
			_bspTree = BSPWorld3D(world).bspTree;
			
			super.render(world, camera, target);
			
			GeneralStatData.polygons += _bspTree.numTriangles;
			GeneralStatData.vertices += _bspTree.numVertices;
		}
		
		override protected function doInitialCulling():void
		{
			var objects : Array = _data.objects;
			
			for (var i : int = 0; i < objects.length; i++) {
				objects[i].isCulled = true;
			}
			 
			_bspTree.addObjects(objects);
			_bspTree.testVisibility(_camera);
		}
		
		override protected function doViewTransform(world:World3D):void
		{
			super.doViewTransform(world);
			_bspTree.transformToViewCoords(_data, _camera);
		}
		
		override protected function doRasterization(target : Viewport) : void
		{
			var triangle : Triangle3D;
			target.clear();
			// bspTree will take care of rendering seperate objects
			// move actual rasterization to renderer which BSP can use
			// node can be rendered first without sorting, then the objects with sorting
			_bspTree.render(_camera, target, _rasterizer, _data);
		}
	}
}